<?php

namespace App\Models\Payment\Repositories;

use App\Models\Payment\Payment;
use App\Models\Payment\PaymentLogs;
use App\Models\Payment\Repositories\Interfaces\PaymentLogsRepositoryInterface;
use App\Models\Payment\Repositories\Interfaces\PaymentRepositoryInterface;
use App\Trip\Repository\BaseRepository;
use Exception;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Validator;

class PaymentRepository extends BaseRepository implements PaymentRepositoryInterface
{

    /**
     * @var PaymentLogsRepositoryInterface $payLogRepo
     */
    private $payLogRepo;

    public function __construct(Payment $model)
    {
        parent::__construct($model);
        $this->payLogRepo = app(PaymentLogsRepositoryInterface::class);
    }

    /**
     * @throws Exception
     */
    public function addPayment(array $data): Payment
    {
        $validator = Validator::make($data, [
            'mchid'       => "required",
            'secret_key'  => "required",
            'secret_key2' => "required",
        ]);
        if ($validator->fails()) {
            throw new Exception("参数错误");
        }
        if ($payment = $this->findOnePaymentByMchId($data['mchid'])) {
            $this->update($data, $payment);
            $payment->refresh();
        } else {
            $payment = $this->create($data);
        }
        $this->payLogRepo->saveLog($payment);
        return $payment;
    }

    public function findOnePaymentByMchId(string $mchid): ?Payment
    {
        return $this->findOneBy([
            'mchid' => $mchid,
        ]);
    }

    /**
     * @throws Exception
     */
    public function findOnePaymentOrPayLog(string $mchid = ''): Payment|PaymentLogs
    {
        $cache_key = "Payment:default:{$mchid}";
        if (Cache::has($cache_key)) {
            $payment = Cache::get($cache_key);
        } else {
            $payment = $this->findOnePayment($mchid);
            if ($mchid && !$payment) {
                $payLogRepo = new PaymentLogsRepository(new PaymentLogs());
                $payment    = $payLogRepo->findOneByMchId($mchid);
            }
        }

        if (!$payment) {
            throw new Exception("没有可用的支付");
        }

        return $payment;
    }

    public function findOnePayment(string $mchid = ''): Payment
    {
        if ($mchid) {
            $payment = $this->findOnePaymentByMchId($mchid);
        } else {
            $payment = $this->model->first();
        }
        return $payment;
    }
}